'''
copyright: Copyright (C) 2015-2024, Wazuh Inc.

           Created by Wazuh, Inc. <info@wazuh.com>.

           This program is free software; you can redistribute it and/or modify it under the terms of GPLv2

type: integration

brief: Wazuh is able to detect vulnerabilities in the applications installed in agents using the Vulnerability Detector
       module. This software audit is performed through the integration of vulnerability feeds indexed by Redhat,
       Canonical, Debian, Amazon Linux and NVD Database.

components:
    - vulnerability_detector

suite: scan_results

targets:
    - manager

daemons:
    - wazuh-modulesd
    - wazuh-db
    - wazuh-analysisd

os_platform:
    - linux

os_version:
    - Arch Linux
    - Amazon Linux 2
    - Amazon Linux 1
    - CentOS 8
    - CentOS 7
    - Debian Buster
    - Red Hat 8
    - Ubuntu Focal
    - Ubuntu Bionic
    - SUSE Enterprise Desktop 11
    - SUSE Enterprise Desktop 12
    - SUSE Enterprise Desktop 15
    - SUSE Enterprise Server 11
    - SUSE Enterprise Server 12
    - SUSE Enterprise Server 15

references:
    - https://documentation.wazuh.com/current/user-manual/capabilities/vulnerability-detection/index.html

tags:
    - vulnerability
    - vulnerability_detector
    - scan_results
'''
import pytest
from pathlib import Path

from wazuh_testing.constants.daemons import ANALYSISD_DAEMON, MODULES_DAEMON, SYSCHECK_DAEMON
from wazuh_testing.utils.db_queries import agent_db
from wazuh_testing.tools.monitors.file_monitor import FileMonitor
from wazuh_testing.constants.paths.logs import WAZUH_LOG_PATH
from wazuh_testing.utils.callbacks import generate_callback
from wazuh_testing.utils.configuration import (get_test_cases_data, load_configuration_template,
                                               update_configuration_template)
from wazuh_testing.modules.modulesd.vulnerability_detector import patterns as cb
from wazuh_testing.modules.modulesd.configuration import MODULESD_DEBUG
from wazuh_testing.modules.monitord.configuration import MONITORD_ROTATE_LOG
from wazuh_testing.utils.mocking import VULNERABLE_PACKAGES
from test_vulnerability_detector import utils as ev
from . import (TEST_CASES_PATH, CONFIGURATIONS_PATH, custom_rhel_oval_feed_path,
               custom_rhel_json_feed_path, custom_nvd_json_feed_path)


pytest.skip("The tests will be deprecated, they test the old Vulnerability Detector.", allow_module_level=True)

# Variables
local_internal_options = {MODULESD_DEBUG: '2', MONITORD_ROTATE_LOG: '0'}
daemons_handler_configuration = {'daemons': [ANALYSISD_DAEMON, MODULES_DAEMON, SYSCHECK_DAEMON]}
pytestmark = [pytest.mark.server]

# Configuration and cases data
configurations_path = Path(CONFIGURATIONS_PATH, 'configuration_scan_vulnerabilities_triaged_null.yaml')
cases_path = Path(TEST_CASES_PATH, 'cases_scan_vulnerabilities_triaged_null.yaml')

# Scan vulnerabilities with null triaged triaged field configurations
configuration_parameters, configuration_metadata, case_ids = get_test_cases_data(cases_path)
configurations = load_configuration_template(configurations_path, configuration_parameters,
                                             configuration_metadata)
systems = [metadata['system'] for metadata in configuration_metadata]

# Set offline custom feeds configuration
configurations = update_configuration_template(
    configurations,  ['CUSTOM_REDHAT_OVAL_FEED', 'CUSTOM_REDHAT_JSON_FEED', 'CUSTOM_NVD_JSON_FEED'],
    [custom_rhel_oval_feed_path, custom_rhel_json_feed_path, custom_nvd_json_feed_path])


@pytest.mark.tier(level=1)
@pytest.mark.parametrize('test_configuration, test_metadata, agent_system',
                         zip(configurations, configuration_metadata, systems), ids=case_ids)
def test_scan_triaged_null_vulnerabilities(test_configuration, test_metadata, agent_system, set_wazuh_configuration,
                                           configure_local_internal_options, truncate_monitored_files,
                                           clean_cve_tables, prepare_full_scan, daemons_handler):
    '''
    description: Check if a vulnerable package with triaged NULL, is detected with the partial scan.

    test_phases:
        - setup:
            - Set a custom Wazuh configuration.
            - Mock an agent.
            - Clean CVE table.
            - Force a full scan.
            - Restart wazuh-modulesd.
        - test:
            - Insert a vulnerable package with triaged NULL.
            - Check that after partial scan triaged changes to 1.
        - teardown:
            - Restart initial wazuh configuration.
            - Clean CVE table.

    wazuh_min_version: 4.4.0

    tier: 1

    parameters:
        - test_configuration:
            type: dict
            brief: Configuration loaded from `configuration_template`.
        - test_metadata:
            type: dict
            brief: Test case metadata.
        - agent_system:
            type: str
            brief: System to set to the mocked agent.
        - set_wazuh_configuration:
            type: fixture
            brief: Set wazuh configuration.
        - configure_local_internal_options:
            type: fixture
            brief: Set local_internal_options configuration.
        - truncate_monitored_files:
            type: fixture
            brief: Truncate all the log files and json alerts files before and after the test execution.
        - clean_cve_tables:
            type: fixture
            brief: Clean all CVE tables.
        - prepare_full_scan:
            type: fixture
            brief: Setup the initial test state.
        - daemons_handler:
            type: fixture
            brief: Restart wazuh-modulesd daemon before starting a test, and stop it after finishing.

    assertions:
        - Verify that the log a partial scan will be run on agent appears in ossec.log.
        - Verify that the triaged field of sys_programs table has changed to 1.

    input_description:
        - The `configuration_scan_vulnerabilities_triaged_null.yaml` file provides the module configuration for this
          test.
        - The `cases_scan_vulnerabilities_triaged_null.yaml` file provides the test cases.

    expected_output:
        - f"A partial scan will be run on agent '{agent_id}'"
    '''
    file_monitor = FileMonitor(WAZUH_LOG_PATH)
    agent_id = prepare_full_scan
    package = VULNERABLE_PACKAGES[0]

    # Insert mocked vulnerables packages.
    agent_db.insert_package(name=package['name'], version=package['version'],
                            source=package['name'], agent_id=agent_id,
                            vendor='Red Hat, Inc.', triaged=test_metadata['triaged'])

    triage_value = agent_db.get_triaged_value_from_inventory(package['name'], agent_id=agent_id)
    assert triage_value == test_metadata['triaged'], 'Triaged value of sys_programs table should be '' before scan'

    # Update packages sync status.
    agent_db.update_sync_info(agent_id=agent_id, component="syscollector-packages")

    # Check for the next partial scan
    file_monitor.start(callback=generate_callback(regex=cb.PARTIAL_SCAN_START,
                                                  replacement={"agent_id": agent_id}))
    assert file_monitor.callback_result is not None, f"No Partial scan start log found."

    triage_value = agent_db.get_triaged_value_from_inventory(package['name'], agent_id=agent_id)
    assert triage_value == 1, 'Triaged value of sys_programs should be 1 after partial scan of vulnerable package.'
